/**
 * 
 */
package nl.samenloop.bigscreen.sequence;

import java.awt.Container;
import java.awt.Font;
import java.awt.FontMetrics;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;

import javax.swing.JComponent;

import nl.samenloop.bigscreen.Constants;
import nl.samenloop.bigscreen.communication.ProgramReader;
import nl.samenloop.bigscreen.communication.Result;
import nl.samenloop.bigscreen.model.ProgramItem;

/**
 * @author Bram Wiekens
 * 
 */
public class ProgramSequence extends Sequence {

	public static final int NOW_STAGE = 0;
	public static final int NEXT_STAGE = 1;

	public static final int NOW_FIELD = 2;
	public static final int NEXT_FIELD = 3;

	private int part;

	public ProgramSequence(DrawingTarget target, int part) {
		super(target, Constants.PROGRAM_TIME);

		this.part = part;
	}

	ProgramItem currentStage;
	ProgramItem currentField;

	List<ProgramItem> nextStage = new ArrayList<ProgramItem>();
	List<ProgramItem> nextField = new ArrayList<ProgramItem>();

	@Override
	public void start() {

		selectPart(part);

	}

	private void selectPart(int part) {
		switch (part) {
		case NOW_STAGE:
			if (currentStage == null) {
				nextStageScreen();
			} else {
				nowStageScreen();
			}
			break;
		case NEXT_STAGE:
			nextStageScreen();
			break;
		case NOW_FIELD:
			if (currentField == null) {
				nextFieldScreen();
			} else {
				nowFieldScreen();
			}
			break;
		case NEXT_FIELD:
			nextFieldScreen();
			break;
		}

	}

	private void nowStageScreen() {
		if (currentStage != null) {
			String start = currentStage.getStartTime();
			String end = currentStage.getEndTime();

			String time = start + " - " + end;

			Container c = target.getCenterContainer();

			JComponent label = createLabel(time, 40,false);
			label.setBounds(10, 10, label.getPreferredSize().width, label.getPreferredSize().height);

			String titleStr = 	String.format("<html><div WIDTH=%d>%s</div><html>", c.getWidth(), currentStage.getTitle());
			
			JComponent title = createLabel(titleStr, 60, false);
			
				
			title.setBounds(50, 80, title.getPreferredSize().width, title.getPreferredSize().height);

			c.add(label);
			c.add(title);

		}

		start(getTitle(Constants.NOW_STAGE));
	}

	private void nowFieldScreen() {
		if (currentField != null) {
			String start = currentField.getStartTime();
			String end = currentField.getEndTime();

			String time = start + " - " + end;

			Container c = target.getCenterContainer();

			JComponent label = createLabel(time, 40,false);
			label.setBounds(10, 10, label.getPreferredSize().width, label.getPreferredSize().height);

			String titleStr = 	String.format("<html><div WIDTH=%d>%s</div><html>", c.getWidth(), currentField.getTitle());
			
			JComponent title = createLabel(titleStr, 60, false);
			
				
			title.setBounds(50, 80, title.getPreferredSize().width, title.getPreferredSize().height);

			c.add(label);
			c.add(title);

		}


		start(getTitle(Constants.NOW_FIELD));
	}

	private void nextStageScreen() {
		int offset = 120;
		int i = 0;

		if (nextStage.size() > 0) {
			for (int index = 0; i < nextStage.size(); index++){
			//for (ProgramItem item : nextStage) {
				ProgramItem item = nextStage.get(index);
				
				String start = item.getStartTime();
				String end = item.getEndTime();

				String time = start + " - " + end;

				Container c = target.getCenterContainer();
				String titleStr = String.format("<html><div WIDTH=%d>%s<br><b>&nbsp;&nbsp;&nbsp;%s</b></div><html>", c.getWidth(), time,  item.getTitle());

				JComponent label = createLabel(titleStr, 40, false);
				label.setBounds(10, 10 + (i * offset), label.getPreferredSize().width, label.getPreferredSize().height);

				c.add(label);

				i++;
			}

		}

		start(getTitle(Constants.NEXT_STAGE));
	}

	private void nextFieldScreen() {
		int offset = 120;
		int i = 0;

		if (nextField.size() > 0) {
			for (int index = 0; i < nextField.size(); index++){
			//for (ProgramItem item : nextStage) {
				ProgramItem item = nextField.get(index);
				
				String start = item.getStartTime();
				String end = item.getEndTime();

				String time = start + " - " + end;

				Container c = target.getCenterContainer();
				String titleStr = String.format("<html><div WIDTH=%d>%s<br><b>&nbsp;&nbsp;&nbsp;%s</b></div><html>", c.getWidth(), time,  item.getTitle());

				JComponent label = createLabel(titleStr, 40, false);
				label.setBounds(10, 10 + (i * offset), label.getPreferredSize().width, label.getPreferredSize().height);

				c.add(label);

				i++;
			}

		}

		start(getTitle(Constants.NEXT_FIELD));
	}

	private Calendar parseTime(String time) {

		String hourStr = time.substring(0, 2);
		String minuteStr = time.substring(3);

		int hour = Integer.parseInt(hourStr);
		int minute = Integer.parseInt(minuteStr);

		Calendar cal = Calendar.getInstance();

		cal.set(Calendar.HOUR_OF_DAY, hour);
		cal.set(Calendar.MINUTE, minute);
		cal.set(Calendar.SECOND, 0);
		
		if (hour < 15 ) {
			int day = cal.get(Calendar.DATE);
			cal.set(Calendar.DATE, ++day);
		}

		return cal;

	}

	private boolean isCurrent(ProgramItem item) {
		String beginTimeStr = item.getStartTime();
		String endTimeStr = item.getEndTime();

		Calendar now = Calendar.getInstance();

		try {

			Calendar begin = parseTime(beginTimeStr);
			Calendar end = parseTime(endTimeStr);

			if (begin.before(now) && end.after(now)) {
				return true;
			}
		} catch (NumberFormatException nfe) {

		}
		return false;
	}

	private boolean isNext(ProgramItem nextItem) {
		Calendar now = Calendar.getInstance();

		String beginTimeStr = nextItem.getStartTime();
		Calendar next = parseTime(beginTimeStr);

		return (next.after(now));
	}

	private void processStageItems(ArrayList<ProgramItem> items) {
		currentStage = null;
		
		for (ProgramItem item : items) {
			if (isCurrent(item)) {
				currentStage = item;
			}

		}

		int i = 0;

		nextStage.clear();

		for (ProgramItem item : items) {
			if (isNext(item)) {
				nextStage.add(item);
				i++;
			}

			if (i > 1)
				break;

		}

	}

	private void processFieldItems(ArrayList<ProgramItem> items) {
		currentField = null;
		
		
		for (ProgramItem item : items) {
			if (isCurrent(item)) {
				currentField = item;
			}

		}

		int i = 0;

		nextField.clear();

		for (ProgramItem item : items) {
			if (isNext(item)) {
				nextField.add(item);
				i++;
			}

			if (i > 1)
				break;

		}

	}

	public void prepareStage() {
		ProgramReader reader = new ProgramReader(Constants.getProperty(Constants.STAGE_URL));

		reader.setResultHandler(new Result<ArrayList<ProgramItem>>() {

			@Override
			public void onSucces(ArrayList<ProgramItem> result) {
				processStageItems(result);

			}

			@Override
			public void onFailure(Throwable e) {
				// TODO Auto-generated method stub
				e.printStackTrace();
			}
		});

		Thread t = new Thread(reader);
		t.start();
	}

	public void prepareField() {
		ProgramReader reader = new ProgramReader(Constants.getProperty(Constants.FIELD_URL));

		reader.setResultHandler(new Result<ArrayList<ProgramItem>>() {

			@Override
			public void onSucces(ArrayList<ProgramItem> result) {
				processFieldItems(result);

			}

			@Override
			public void onFailure(Throwable e) {
				// TODO Auto-generated method stub
				e.printStackTrace();
			}
		});

		Thread t = new Thread(reader);
		t.start();
	}

	@Override
	public void prepare() {
		switch (part) {
		case NOW_STAGE:
			prepareStage();
			break;
		case NEXT_STAGE:
			prepareStage();
			break;
		case NOW_FIELD:
			prepareField();
			break;
		case NEXT_FIELD:
			prepareField();
			break;
		}
	}

}
